home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 001 / pibt40s1.arc / INT24.MOD < prev    next >
Text File  |  1986-03-01  |  10KB  |  214 lines

  1. { Version 2.0, 1/28/86
  2.   For MS-DOS version 2.0 or greater, Turbo Pascal 1.0 or greater.
  3.  
  4.   Thanks to Marshall Brain for the original idea for these routines.
  5.   Thanks to John Cooper for pointing out a small flaw in the code.
  6.  
  7.   These routines provide a method for Turbo Pascal programs to trap MS-DOS
  8. interrupt 24 (hex).  INT 24h is called by DOS when a 'critical error' occurs,
  9. and it normally prints the familiar "Abort, Retry, Ignore?" message.
  10.  
  11.   With the INT 24h handler installed, errors of this type will be passed on to
  12. Turbo Pascal as an error.  If I/O checking is on, this will cause a program
  13. crash.  If I/O checking is off, IOResult will return an error code.  The
  14. global variable INT24Err will be true if an INT 24h error has occurred.  The
  15. variable INT24ErrorCode will contain the INT 24h error code as given by DOS.
  16. These errors can be found in the DOS Technical Reference Manual.
  17.   It is intended that INT24Result be used in place of IOResult.  Calling
  18. INT24Result clears IOResult.  The simple way to use INT24Result is just to
  19. check that it returns zero, and if not, handle all errors the same.  The more
  20. complicated way is to interpret the code.  The integer returned by INT24Result
  21. can be looked at as two bytes.  By assigning INT24Result to a variable, you
  22. can then examine the two bytes: (Hi(<variable>)-1) will give the DOS critical
  23. error code, or (<variable> And $FF00) will return an integer from the table
  24. listed in the INT24Result procedure (two ways of looking at the critical
  25. error); Lo(<variable>) will give Turbo's IOResult.  A critical error will
  26. always be reflected in INT24Result, but the IOResult part of INT24Result will
  27. not necessarily be nonzero; in particular, unsuccessful writes to character
  28. devices will not register as a Turbo I/O error.
  29.  
  30.   INT24Result should be called after any operation which might cause a
  31. critical error, if Turbo's I/O checking is disabled.  If it is enabled, the
  32. program will be aborted except in the above noted case of writes to character
  33. devices.
  34.  
  35.   Also note that different versions of DOS and the BIOS seem to react to
  36. printer errors at vastly different rates.  Be prepared to wait a while for
  37. anything to happen (in an error situation) on some machines.
  38.  
  39.   These routines are known to work correctly with: Turbo Pascal 1.00B PC-DOS;
  40.                                                    Turbo Pascal 2.00B PC-DOS;
  41.                                                    Turbo Pascal 2.00B MS-DOS;
  42.                                                    Turbo Pascal 3.01A PC-DOS.
  43.   Other MS-DOS and PC-DOS versions should work.
  44.  
  45.   Note that Turbo 2.0's normal IOResult codes for MS-DOS DO NOT correspond to
  46. the I/O error numbers given in Appendix I of the Turbo 2.0 manual, or to the
  47. error codes given in the I/O error nn, PC=aaaa/Program aborted message.  Turbo
  48. 3.0 IOResult codes do match the manual.  Here is a table of the correspondence
  49. (all numbers in hexadecimal):
  50.  
  51.   Turbo 2.0 IOResult    Turbo error, Turbo 3.0 IOResult
  52.   ------------------    -------------------------------------------------
  53.      00                 00  none
  54.      01                 90  record length mismatch
  55.      02                 01  file does not exist
  56.      03                 F1  directory is full
  57.      04                 FF  file disappeared
  58.      05                 02  file not open for input
  59.      06                 03  file not open for output
  60.      07                 99  unexpected end of file
  61.      08                 F0  disk write error
  62.      09                 10  error in numeric format
  63.      0A                 99  unexpected end of file
  64.      0B                 F2  file size overflow
  65.      0C                 99  unexpected end of file
  66.      0D                 F0  disk write error
  67.      0E                 91  seek beyond end of file
  68.      0F                 04  file not open
  69.      10                 20  operation not allowed on a logical device
  70.      11                 21  not allowed in direct mode
  71.      12                 22  assign to standard files is not allowed
  72.  
  73.   -  Bela Lubkin
  74.      CompuServe 76703,3015
  75.      1/28/86
  76. }
  77.  
  78. Procedure INT24;
  79.   Const FCBFuncs: Array [1..6] Of Byte=(14,15,21,22,27,28);
  80.   Begin
  81.     { To understand this routine, you will need to read the description of
  82.       Interrupt 24h in the DOS manual.  It also helps to examine and trace the
  83.       generated code under DEBUG. }
  84.     Inline($0E/$0E/$1F/$07/$C6/$06/ INT24Err /$01/$89/$EC/$83/$C4/$08/
  85.            $89/$F8/$A2/ INT24ErrCode /$58/$B9/$06/$00/$BF/ FCBFuncs /$F2/
  86.            $AE/$75/$04/$B0/$01/$EB/$08/$3C/$39/$B0/$FF/$72/$02/$B0/$83/
  87.            $5B/$59/$5A/$5E/$5F/$89/$E5/$80/$4E/$0A/$01/$5D/$1F/$07/$CF);
  88. {   Turbo:  PUSH BP                    (Save caller's stack frame
  89.             MOV  BP,SP                   Set up this procedure's stack frame
  90.             PUSH BP                     ?)
  91.     Inline: PUSH CS
  92.             PUSH CS
  93.             POP  DS                    Set DS and ES temporarily to CS
  94.             POP  ES
  95.             MOV  BYTE [INT24Err],1     Set INT24Err to True  (CS:)
  96.             MOV  SP,BP                 Get correct SP;  ADD: Discard saved
  97.             ADD  SP,8                    BP, INT 24h return address & flags
  98.             MOV  AX,DI                 Get INT 24h error code
  99.             MOV  [INT24ErrCode],AL     Save it in INT24ErrCode
  100.             POP  AX                    Get initial DOS call number
  101.             MOV  CX,6                  Search for it in FCBFuncs: is this one
  102.             MOV  DI,Offset FCBFuncs      of the FCB functions that requires an
  103.             REPNZ SCASB                  error code of 01 in AL?
  104.             JNZ  .1
  105.             MOV  AL,1                  Yes: set it
  106.             JMP  .2
  107.     .1      CMP  AL,39h                No: is it an FCB function that requires
  108.             MOV  AL,0FFh                 AL=FFh (function <39h)?  Yes: set it.
  109.             JB   .2
  110.             MOV  AL,83h                No: handle call, return error 83h, call
  111.                                          failed via INT 24h.
  112.                                        The error code (1, FFh or 83h) is
  113.                                          returned to the Turbo runtime routine
  114.                                          that called DOS, making it look like
  115.                                          a simple DOS error.  Turbo handles
  116.                                          the I/O error.
  117.     .2      POP  BX                    Pop the rest of the registers saved by
  118.             POP  CX                      the initial INT 21h.
  119.             POP  DX
  120.             POP  SI
  121.             POP  DI
  122.             MOV  BP,SP
  123.             OR   Byte Ptr [BP+0Ah],1   Set the carry flag in the saved Flags reg.
  124.             POP  BP
  125.             POP  DS
  126.             POP  ES
  127.             IRET                       Return to next instruction: all regs.
  128.                                          restored, AL=error code, carry set. }
  129.   End;
  130.  
  131. Procedure INT24On;  { Enable INT 24h trapping }
  132.   Begin
  133.     INT24Err:=False;
  134.     With RegisterSet Do
  135.      Begin
  136.       AX:=$3524;
  137.       MsDos(RegisterSet);
  138.       If (OldINT24[1] Or OldINT24[2])=0 Then
  139.        Begin
  140.         OldINT24[1]:=ES;
  141.         OldINT24[2]:=BX;
  142.        End;
  143.       DS:=CSeg;
  144.       DX:=Ofs(INT24);
  145.       AX:=$2524;
  146.       MsDos(RegisterSet);
  147.      End;
  148.   End;
  149.  
  150. Procedure INT24Off;  { Disable INT 24h trapping.  Should be done at the end of
  151.                        the program, if you plan to run the program from within
  152.                        the Turbo compiler.  If the INT 24h handler is left in
  153.                        place, and the compiler gets a critical error, the
  154.                        system is likely to crash. }
  155.   Begin
  156.     INT24Err:=False;
  157.     If OldINT24[1]<>0 Then
  158.       With RegisterSet Do
  159.        Begin
  160.         DS:=OldINT24[1];
  161.         DX:=OldINT24[2];
  162.         AX:=$2524;
  163.         MsDos(RegisterSet);
  164.        End;
  165.     OldINT24[1]:=0;
  166.     OldINT24[2]:=0;
  167.   End;
  168.  
  169. Function INT24Result: Integer;
  170.   Var
  171.     I:Integer;
  172.  
  173.   Begin
  174.     I:=IOResult;
  175.     If INT24Err Then
  176.      Begin
  177.       I:=I+256*Succ(INT24ErrCode);
  178.       INT24On;
  179.      End;
  180.     INT24Result:=I;
  181.   End;
  182. { INT24Result returns all the regular Turbo IOResult codes if no critical
  183.   error has occurred.  If a critical error, then the following values are
  184.   added to the error code from Turbo:
  185.    256:  Attempt to write on write protected disk
  186.    512:  Unknown unit                 [internal dos error]
  187.    768:  Drive not ready              [drive door open or bad drive]
  188.    1024: Unknown command              [internal dos error]
  189.    1280: Data error (CRC)             [bad sector or drive]
  190.    1536: Bad request structure length [internal dos error]
  191.    1792: Seek error                   [bad disk or drive]
  192.    2048: Unknown media type           [bad disk or drive]
  193.    2304: Sector not found             [bad disk or drive]
  194.    2560: Printer out of paper         [anything that the printer might signal]
  195.    2816: Write fault                  [character device not ready]
  196.    3072: Read fault                   [character device not ready]
  197.    3328: General failure              [several meanings]
  198.  
  199.   If you need the IOResult part, use
  200.    I:=INT24Result and 255; [masks out the INT 24h code]
  201.  
  202.   For the INT 24h code, use
  203.    I:=INT24Result Shr 8;   [same as Div 256, except faster]
  204.  
  205.   INT24Result clears both error codes, so you must assign it to a variable if
  206.   you want to extract both codes:
  207.    J:=INT24Result;
  208.    WriteLn('Turbo IOResult  = ',J And 255);
  209.    WriteLn('DOS INT 24h code = ',J Shr 8);
  210.  
  211.   Note that in most cases, errors on character devices (LST and AUX) will not
  212.   return an IOResult, only an INT 24h error code. }
  213. 
  214.